import json
import logging
import os
from pathlib import Path
from typing import Dict, List, Optional, Any, Union, Literal, Tuple
import base64
import binascii
from cryptography.fernet import Fernet, InvalidToken
from secure_config_manager.core.encryption import EnhancedAES256Encryptor

logger = logging.getLogger(__name__)

# 定义支持的文件类型
FileType = Literal["json", "text", "binary"]

class SecureConfigManager:
    """
    安全文件管理器，用于管理加密的JSON、文本和二进制文件。
    """
    DEFAULT_CONFIG_DIR = "configs"
    FILE_EXTENSIONS: Dict[str, Any] = {
        "json": [".json"],
        "text": [".txt", ".py", ".js", ".md", ".csv", ".log", ".ini", ".conf", ".xml", ".html", ".css", ".sh", ".bat", ".yml", ".yaml"],
        "binary": [
            ".bin", ".exe", ".dll", ".so", ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".ico", ".pdf", ".zip", ".tar", ".gz", ".7z", ".rar",
            ".mp3", ".wav", ".ogg", ".mp4", ".avi", ".mov", ".mkv", ".flv", ".webm", ".apk", ".dmg", ".iso", ".img"
        ],
    }
    ENCRYPTED_SUFFIX = ".enc"

    def __init__(self, config_dir: str = DEFAULT_CONFIG_DIR):
        """
        初始化安全文件管理器。

        参数:
            config_dir: 存储文件的目录。
        """
        self.config_dir = Path(config_dir).resolve() # 使用绝对路径
        self.config_dir.mkdir(parents=True, exist_ok=True) # 确保目录存在
        logger.info(f"SecureConfigManager 已初始化，目录：{self.config_dir}")

    def _get_path(self, name: str, file_type: FileType = "json", encrypted: bool = False, custom_ext: Optional[str] = None) -> Path:
        """
        构造文件的完整路径。
        
        参数:
            name: 文件基础名称 (不带扩展名)。
            file_type: 文件类型 ('json', 'text', 'binary')，默认为'json'。
            encrypted: 是否获取加密文件的路径。
            custom_ext: 可选，指定自定义扩展名（如 .py、.js 等，仅对 text 类型有效）。
        
        返回:
            文件的完整Path对象。
        """
        # 处理绝对路径的情况
        path = Path(name)
        if path.is_absolute():
            logger.debug(f"提供的名称 '{name}' 是绝对路径")
            
            # 检查是否已经包含了扩展名
            if path.suffix:
                # 如果已经有扩展名，则根据encrypted状态决定是否添加.enc
                if encrypted and not path.suffix.endswith(self.ENCRYPTED_SUFFIX):
                    return path.with_suffix(path.suffix + self.ENCRYPTED_SUFFIX)
                elif not encrypted and path.suffix.endswith(self.ENCRYPTED_SUFFIX):
                    # 如果是加密文件但请求明文路径
                    suffix = path.suffix
                    return path.with_suffix(suffix[:-len(self.ENCRYPTED_SUFFIX)])
                return path
            
            # 没有扩展名的绝对路径，需要添加扩展名
            # 此时仍然使用 file_type 来确定扩展名
            extensions = self.FILE_EXTENSIONS.get(file_type)
            if not extensions:
                raise ValueError(f"不支持的文件类型: {file_type}")
            
            if custom_ext and file_type == "text":
                extension = custom_ext if custom_ext.startswith(".") else f".{custom_ext}"
            else:
                extension = extensions[0] if isinstance(extensions, list) else extensions
            
            suffix = f"{extension}{self.ENCRYPTED_SUFFIX}" if encrypted else extension
            return Path(f"{path}{suffix}")
            
        # 处理相对路径的情况（正常情况）
        extensions = self.FILE_EXTENSIONS.get(file_type)
        if not extensions:
            raise ValueError(f"不支持的文件类型: {file_type}")
        
        # 允许自定义扩展名（仅text类型）
        if custom_ext and file_type == "text":
            extension = custom_ext if custom_ext.startswith(".") else f".{custom_ext}"
        else:
            extension = extensions[0] if isinstance(extensions, list) else extensions
            
        suffix = f"{extension}{self.ENCRYPTED_SUFFIX}" if encrypted else extension
        return self.config_dir / f"{name}{suffix}"

    def _get_file_info(self, path: Path) -> Tuple[Optional[str], Optional[FileType], Optional[bool]]:
        """
        从文件路径中提取文件信息。
        
        参数:
            path: 文件路径
        
        返回:
            元组 (basename, file_type, is_encrypted)，如果不是受支持的文件则为 (None, None, None)
        """
        name = path.name
        is_encrypted = name.endswith(self.ENCRYPTED_SUFFIX)
        
        if is_encrypted:
            # 移除.enc后缀再检查文件类型
            name_without_enc = name[:-len(self.ENCRYPTED_SUFFIX)]
            for file_type, exts in self.FILE_EXTENSIONS.items():
                if isinstance(exts, list):
                    for ext in exts:
                        if name_without_enc.endswith(ext):
                            basename = name_without_enc[:-len(ext)]
                            return basename, file_type, True
                else:
                    if name_without_enc.endswith(exts):
                        basename = name_without_enc[:-len(exts)]
                        return basename, file_type, True
        else:
            # 检查明文文件类型
            for file_type, exts in self.FILE_EXTENSIONS.items():
                if isinstance(exts, list):
                    for ext in exts:
                        if name.endswith(ext):
                            basename = name[:-len(ext)]
                            return basename, file_type, False
                else:
                    if name.endswith(exts):
                        basename = name[:-len(exts)]
                        return basename, file_type, False
        # 未找到匹配的文件类型
        return None, None, None

    def list_configs(self, file_type: Optional[FileType] = None) -> List[Dict[str, Any]]:
        """
        列出配置目录中的所有受管理文件。
        
        参数:
            file_type: 可选，用于过滤特定类型的文件。
        
        返回:
            文件信息列表，每个元素是一个字典，包含 'name', 'type', 'status' ('encrypted' 或 'plaintext')。
        """
        configs = []
        types_to_scan = [file_type] if file_type else list(self.FILE_EXTENSIONS.keys())
        try:
            all_files = list(self.config_dir.iterdir()) # 获取所有文件
            logger.debug(f"扫描目录 {self.config_dir} 中的 {len(all_files)} 个条目")
            processed_names = set() # 记录已处理的基础名，避免重复
            for path in all_files:
                if not path.is_file():
                    continue # 跳过目录
                basename, current_type, is_encrypted = self._get_file_info(path)
                if basename and current_type:
                    if current_type in types_to_scan:
                        # 如果这个基础名还没处理过
                        if (basename, current_type) not in processed_names:
                            status = "encrypted" if is_encrypted else "plaintext"
                            # 检查是否同时存在加密和明文版本
                            if current_type == "text":
                                encrypted_exists = False
                                plaintext_exists = False
                                for ext in self.FILE_EXTENSIONS["text"]:
                                    if (self.config_dir / f"{basename}{ext}{self.ENCRYPTED_SUFFIX}").exists():
                                        encrypted_exists = True
                                    if (self.config_dir / f"{basename}{ext}").exists():
                                        plaintext_exists = True
                                if encrypted_exists and plaintext_exists:
                                    status = "both"
                                elif encrypted_exists:
                                    status = "encrypted"
                                elif plaintext_exists:
                                    status = "plaintext"
                            else:
                                encrypted_path = self._get_path(basename, current_type, encrypted=True)
                                plaintext_path = self._get_path(basename, current_type, encrypted=False)
                                if encrypted_path.exists() and plaintext_path.exists():
                                    status = "both" # 明文和加密版本都存在
                            configs.append({
                                "name": basename,
                                "type": current_type,
                                "status": status
                            })
                            processed_names.add((basename, current_type))
            logger.debug(f"找到 {len(configs)} 个匹配的文件")
            return configs
        except Exception as e:
            logger.error(f"列出目录 {self.config_dir} 中的文件时出错：{e}", exc_info=True)
            return []

    def file_exists(self, name: str, file_type: Optional[FileType] = None) -> bool:
        """
        检查具有给定名称的文件是否存在（检查明文或加密版本）。
        
        参数:
            name: 文件基础名称或绝对路径。
            file_type: 可选，检查特定类型。如果为None，则检查所有已知类型。
            如果name是绝对路径，file_type参数将被忽略。
        
        返回:
            如果任何匹配的文件存在，则为True。
        """
        # 处理绝对路径
        path = Path(name)
        if path.is_absolute():
            logger.debug(f"检查绝对路径文件是否存在: {path}")
            
            # 直接检查该路径
            if path.exists():
                return True
                
            # 检查扩展名
            if path.suffix:
                if path.suffix.endswith(self.ENCRYPTED_SUFFIX):
                    # 检查对应的明文文件
                    plaintext_path = path.with_suffix(path.suffix[:-len(self.ENCRYPTED_SUFFIX)])
                    return plaintext_path.exists()
                else:
                    # 检查对应的加密文件
                    encrypted_path = path.with_suffix(path.suffix + self.ENCRYPTED_SUFFIX)
                    return encrypted_path.exists()
            else:
                # 没有扩展名的绝对路径，检查各类型可能的文件
                for type_key, exts in self.FILE_EXTENSIONS.items():
                    if isinstance(exts, list):
                        for ext in exts:
                            if (path.with_suffix(ext)).exists() or (path.with_suffix(ext + self.ENCRYPTED_SUFFIX)).exists():
                                return True
                    else:
                        if (path.with_suffix(exts)).exists() or (path.with_suffix(exts + self.ENCRYPTED_SUFFIX)).exists():
                            return True
            return False
            
        # 处理相对路径（遍历所有类型和扩展名）
        types_to_check = [file_type] if file_type else list(self.FILE_EXTENSIONS.keys())
        for type_key in types_to_check:
            exts = self.FILE_EXTENSIONS[type_key]
            if isinstance(exts, list):
                for ext in exts:
                    plaintext_path = self.config_dir / f"{name}{ext}"
                    encrypted_path = self.config_dir / f"{name}{ext}{self.ENCRYPTED_SUFFIX}"
                    if plaintext_path.exists() or encrypted_path.exists():
                        return True
            else:
                plaintext_path = self._get_path(name, type_key, encrypted=False)
                encrypted_path = self._get_path(name, type_key, encrypted=True)
                if plaintext_path.exists() or encrypted_path.exists():
                    return True
        return False

    def delete_file(self, name: str, file_type: Optional[FileType] = None) -> bool:
        """
        删除指定的文件（同时删除明文和加密版本）。
        
        参数:
            name: 文件基础名称或绝对路径。
            file_type: 可选，删除特定类型。如果为None，则尝试删除所有匹配名称的已知类型。
            如果name是绝对路径，file_type参数将被忽略。
        
        返回:
            如果至少删除了一个文件，则为True。
        """
        deleted_any = False
        
        # 处理绝对路径
        path = Path(name)
        if path.is_absolute():
            logger.debug(f"尝试删除绝对路径文件: {path}")
            
            paths_to_delete = []
            # 如果有扩展名，只删除该文件及其加密/明文对应版本
            if path.suffix:
                paths_to_delete.append(path)
                if path.suffix.endswith(self.ENCRYPTED_SUFFIX):
                    # 添加对应的明文文件
                    paths_to_delete.append(path.with_suffix(path.suffix[:-len(self.ENCRYPTED_SUFFIX)]))
                else:
                    # 添加对应的加密文件
                    paths_to_delete.append(path.with_suffix(path.suffix + self.ENCRYPTED_SUFFIX))
            else:
                # 没有扩展名，尝试删除各类型可能的文件
                for type_key, exts in self.FILE_EXTENSIONS.items():
                    if isinstance(exts, list):
                        for ext in exts:
                            paths_to_delete.append(path.with_suffix(ext))
                            paths_to_delete.append(path.with_suffix(ext + self.ENCRYPTED_SUFFIX))
                    else:
                        paths_to_delete.append(path.with_suffix(exts))
                        paths_to_delete.append(path.with_suffix(exts + self.ENCRYPTED_SUFFIX))
            
            # 执行删除
            for p in paths_to_delete:
                try:
                    if p.exists():
                        p.unlink()
                        logger.info(f"已删除文件: {p}")
                        deleted_any = True
                except OSError as e:
                    logger.error(f"删除文件 {p} 时出错: {e}")
            
            return deleted_any
        
        # 处理相对路径（遍历所有类型和扩展名）
        types_to_delete = [file_type] if file_type else list(self.FILE_EXTENSIONS.keys())

        for type_key in types_to_delete:
            exts = self.FILE_EXTENSIONS[type_key]
            if isinstance(exts, list):
                for ext in exts:
                    plaintext_path = self.config_dir / f"{name}{ext}"
                    encrypted_path = self.config_dir / f"{name}{ext}{self.ENCRYPTED_SUFFIX}"
                    try:
                        if plaintext_path.exists():
                            plaintext_path.unlink()
                            logger.info(f"已删除明文文件: {plaintext_path}")
                            deleted_any = True
                        if encrypted_path.exists():
                            encrypted_path.unlink()
                            logger.info(f"已删除加密文件: {encrypted_path}")
                            deleted_any = True
                    except OSError as e:
                        logger.error(f"删除文件 {name} ({type_key}) 扩展名 {ext} 时出错: {e}")
                        # 继续尝试删除其他文件，但记录错误
            else:
                plaintext_path = self._get_path(name, type_key, encrypted=False)
                encrypted_path = self._get_path(name, type_key, encrypted=True)
                try:
                    if plaintext_path.exists():
                        plaintext_path.unlink()
                        logger.info(f"已删除明文文件: {plaintext_path}")
                        deleted_any = True
                    if encrypted_path.exists():
                        encrypted_path.unlink()
                        logger.info(f"已删除加密文件: {encrypted_path}")
                        deleted_any = True
                except OSError as e:
                    logger.error(f"删除文件 {name} ({type_key}) 时出错: {e}")
                    # 继续尝试删除其他文件，但记录错误

        if not deleted_any and file_type:
             logger.warning(f"未找到要删除的文件 '{name}' 类型为 '{file_type}'")
        elif not deleted_any:
             logger.warning(f"未找到要删除的文件 '{name}' (任何类型)")

        return deleted_any

    def create_file(self, name: str, file_type: FileType = "json", initial_data: Optional[Any] = None, encrypt: bool = False, force: bool = False, encryptor: Optional[EnhancedAES256Encryptor] = None) -> bool:
        """
        创建新的文件。

        参数:
            name: 文件基础名称。
            file_type: 文件类型 (默认: 'json')。
            initial_data: 文件的初始内容。如果为None，则根据类型使用默认值（{}, "", b""）。
            encrypt: 是否创建加密文件 (需要提供encryptor)。
            force: 如果文件已存在，是否强制覆盖。
            encryptor: 如果 encrypt=True，则需要加密器实例。
            
        返回:
            是否成功创建文件
        """
        if encrypt and not encryptor:
            logger.error("创建加密文件需要提供加密器实例")
            return False

        target_path = self._get_path(name, file_type, encrypted=encrypt)
        plaintext_path = self._get_path(name, file_type, encrypted=False)
        encrypted_path = self._get_path(name, file_type, encrypted=True)

        # 检查是否存在
        if not force and (plaintext_path.exists() or encrypted_path.exists()):
             existing_path = encrypted_path if encrypted_path.exists() else plaintext_path
             logger.warning(f"文件 '{name}' ({file_type}) 已存在于 {existing_path}。使用 force=True 进行覆盖。")
             return False

        # 确定初始数据
        if initial_data is None:
            if file_type == "json":
                initial_data = {}
            elif file_type == "text":
                initial_data = ""
            elif file_type == "binary":
                initial_data = b""

        try:
            # 确保父目录存在
            target_path.parent.mkdir(parents=True, exist_ok=True)

            if encrypt:
                logger.info(f"创建并加密文件: {target_path}")
                if encryptor:
                    self.encrypt_and_save_content(name, initial_data, encryptor, file_type)
                    # 覆盖时删除明文版本
                    if force and plaintext_path.exists():
                         plaintext_path.unlink()
                         logger.debug(f"覆盖时删除了明文文件: {plaintext_path}")
                else:
                    logger.error("无法创建加密文件: 未提供加密器")
                    return False
            else:
                logger.info(f"创建明文文件: {target_path}")
                self.save_file_data(name, initial_data, file_type)
                # 覆盖时删除加密版本
                if force and encrypted_path.exists():
                    encrypted_path.unlink()
                    logger.debug(f"覆盖时删除了加密文件: {encrypted_path}")

            logger.info(f"成功创建文件: {target_path}")
            return True
        except Exception as e:
            logger.error(f"创建文件 {target_path} 失败: {e}", exc_info=True)
            return False

    def save_file_data(self, name: str, data: Any, file_type: FileType = "json") -> bool:
        """
        将明文数据保存到指定文件，根据类型处理。

        参数:
            name: 文件基础名称。
            data: 要保存的数据 (dict/list for json, str for text, bytes for binary)。
            file_type: 文件类型，默认为'json'。
            
        返回:
            是否成功保存
        """
        file_path = self._get_path(name, file_type, encrypted=False)
        logger.info(f"保存明文数据到: {file_path} (类型: {file_type})")
        try:
            file_path.parent.mkdir(parents=True, exist_ok=True)
            if file_type == "json":
                if not isinstance(data, (dict, list)):
                    raise TypeError("JSON 类型需要 dict 或 list 数据")
                json_data = json.dumps(data, indent=4, ensure_ascii=False)
                with open(file_path, 'w', encoding='utf-8') as f:
                    f.write(json_data)
            elif file_type == "text":
                if not isinstance(data, str):
                    data_str = str(data)  # 尝试转换为字符串
                    logger.warning(f"Text类型需要str数据，自动转换 {type(data)} 为str")
                else:
                    data_str = data
                with open(file_path, 'w', encoding='utf-8') as f:
                    f.write(data_str)
            elif file_type == "binary":
                if not isinstance(data, bytes):
                    raise TypeError("Binary 类型需要 bytes 数据")
                with open(file_path, 'wb') as f:
                    f.write(data)
            logger.info(f"成功保存明文数据到 {file_path}")
            return True
        except Exception as e:
            logger.error(f"保存明文数据到 {file_path} 失败: {e}", exc_info=True)
            return False

    def get_file_data(self, name: str, file_type: FileType = "json") -> Optional[Any]:
        """
        从指定的明文文件加载数据，根据类型处理。

        参数:
            name: 文件基础名称。
            file_type: 文件类型，默认为'json'。

        返回:
            加载的数据 (dict/list for json, str for text, bytes for binary)，如果文件不存在或出错则为None。
        """
        file_path = self._get_path(name, file_type, encrypted=False)
        logger.debug(f"尝试加载明文文件: {file_path} (类型: {file_type})")
        if not file_path.exists():
            logger.warning(f"明文文件不存在: {file_path}")
            return None
        try:
            if file_type == "json":
                with open(file_path, 'r', encoding='utf-8') as f:
                    content = f.read()
                    return json.loads(content) if content else {}
            elif file_type == "text":
                with open(file_path, 'r', encoding='utf-8') as f:
                    return f.read()
            elif file_type == "binary":
                with open(file_path, 'rb') as f:
                    return f.read()
            return None # 不应该发生，除非file_type无效
        except json.JSONDecodeError as e:
            logger.error(f"解析 {file_path} 的JSON时出错: {e}")
            return None
        except Exception as e:
            logger.error(f"读取明文文件 {file_path} 时出错: {e}")
            return None

    def create_config(self, filename: str) -> bool:
        """创建一个新的空配置文件。"""
        file_path = self._get_path(filename)
        if file_path.exists():
            logger.warning(f"配置文件已存在：{file_path}")
            return False
        try:
            self.save_config_data(filename, {}) # 创建空的JSON对象
            logger.info(f"已创建新配置文件：{file_path}")
            return True
        except Exception as e:
            logger.error(f"创建配置文件 {file_path} 失败：{e}")
            return False

    def delete_config(self, filename: str) -> bool:
        """删除指定的配置文件。"""
        file_path = self._get_path(filename)
        if not file_path.exists():
            logger.warning(f"要删除的配置文件不存在：{file_path}")
            return False
        try:
            file_path.unlink()
            logger.info(f"已删除配置文件：{file_path}")
            return True
        except Exception as e:
            logger.error(f"删除配置文件 {file_path} 失败：{e}")
            return False

    def get_config_data(self, filename: str) -> Optional[Dict]:
        """从指定的配置文件加载JSON数据。"""
        file_path = self._get_path(filename)
        if not file_path.exists():
            logger.warning(f"配置文件不存在：{file_path}")
            return None
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                content = f.read()
                if not content:
                    return {} # 对于空文件返回空字典
                return json.loads(content)
        except json.JSONDecodeError as e:
            logger.error(f"解析 {file_path} 的JSON时出错：{e}")
            return None # 表示出错
        except Exception as e:
            logger.error(f"读取配置文件 {file_path} 时出错：{e}")
            return None # 表示出错

    def save_config_data(self, filename: str, data: Dict[str, Any]):
        """将JSON数据保存到指定的配置文件。"""
        file_path = self._get_path(filename)
        logger.info(f"准备保存数据到配置文件: {file_path}")
        
        try:
            # 确保父目录存在
            file_path.parent.mkdir(parents=True, exist_ok=True)
            logger.debug(f"已确保配置文件目录存在: {file_path.parent}")
            
            # 进行数据序列化
            json_data = json.dumps(data, indent=4, ensure_ascii=False)
            logger.debug(f"成功序列化JSON数据，大小: {len(json_data)} 字节")

            # 写入文件
            with open(file_path, 'w', encoding='utf-8') as f:
                f.write(json_data)
                
            logger.info(f"成功保存数据到配置文件: {file_path}")
        except json.JSONDecodeError as je:
            error_msg = f"序列化JSON时出错: {je}"
            logger.error(error_msg, exc_info=True)
            raise ValueError(error_msg)
        except IOError as io_err:
            error_msg = f"写入文件 {file_path} 时出错: {io_err}"
            logger.error(error_msg, exc_info=True)
            raise IOError(error_msg)
        except Exception as e:
            error_msg = f"保存数据到 {file_path} 失败: {e}"
            logger.error(error_msg, exc_info=True)
            raise

    def get_encrypted_content(self, filename: str) -> Optional[str]:
        """读取文件的原始（可能是加密的）内容。"""
        file_path = self._get_path(filename)
        if not file_path.exists():
            logger.warning(f"配置文件不存在：{file_path}")
            return None
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                return f.read()
        except Exception as e:
            logger.error(f"从 {file_path} 读取原始内容时出错：{e}")
            return None

    # --- 解密方法 ---

    def _recursive_decrypt(self, content: Any, encryptor: EnhancedAES256Encryptor) -> Any:
        """内部方法，递归解密字典和列表中的加密值。"""
        if isinstance(content, dict):
            # 检查字典是否符合我们的加密数据结构 (版本2或3)
            # 注意：encryptor.decrypt 现在只接受字节或字典，我们传入字典
            required_keys = {'version', 'ciphertext', 'salt', 'nonce', 'tag', 'iterations'}
            if required_keys.issubset(content.keys()) and content.get('version') in [encryptor.CURRENT_VERSION, encryptor.BINARY_VERSION]:
                 # 检查值是否已经是字典形式 (旧版或从二进制解析得到)
                try:
                    # 如果看起来像加密数据，则解密它
                    # encryptor.decrypt 会处理base64解码
                    decrypted_bytes = encryptor.decrypt(content) 
                    # 尝试将解密后的字节解码为UTF-8字符串，如果失败则保持字节
                    try:
                        return decrypted_bytes.decode('utf-8')
                    except UnicodeDecodeError:
                        return decrypted_bytes 
                except (ValueError, InvalidToken, TypeError, binascii.Error) as e:
                    # 解密失败（错误的密钥、损坏的数据、无效的格式、Base64错误）
                    logger.warning(f"解密内嵌加密字典失败: {e}。按原样返回。")
                    return content # 解密失败时返回原始字典
            else:
                # 如果是普通字典，递归到其值
                decrypted_dict = {}
                for k, v in content.items():
                    decrypted_dict[k] = self._recursive_decrypt(v, encryptor)
                return decrypted_dict
        elif isinstance(content, list):
            # 递归到列表项
            return [self._recursive_decrypt(item, encryptor) for item in content]
        else:
            # 对于非字典、非列表类型（如str、int、float、bool），按原样返回
            return content

    def _finalize_decrypted_json(self, item: Any) -> Any:
        """递归地将解密后的字节（如果代表JSON）解析回Python对象。"""
        if isinstance(item, bytes):
            try:
                # 尝试解析为 JSON
                return json.loads(item.decode('utf-8'))
            except (json.JSONDecodeError, UnicodeDecodeError):
                logger.debug("Decrypted bytes block could not be parsed as JSON, attempting decode to string.")
                try:
                    # 如果不是 JSON，尝试解码为字符串
                   return item.decode('utf-8')
                except UnicodeDecodeError:
                   logger.warning("Decrypted bytes block could not be decoded as UTF-8, returning raw bytes.")
                   return item # 最后手段：返回原始字节
        elif isinstance(item, dict):
            return {k: self._finalize_decrypted_json(v) for k, v in item.items()}
        elif isinstance(item, list):
            return [self._finalize_decrypted_json(i) for i in item]
        else:
            return item

    def get_decrypted_file_content(self, name: str, encryptor: EnhancedAES256Encryptor, file_type: FileType = "json") -> Optional[Any]:
        """
        加载、解密并返回文件内容。对于JSON类型，会进行递归解密。

        参数:
            name: 文件基础名称。
            encryptor: 加密器实例。
            file_type: 文件类型，默认为'json'。

        返回:
            解密后的数据 (dict/list for json, str for text, bytes for binary)，如果出错则为None。
        """
        # 优先尝试读取 .enc 文件
        encrypted_path = self._get_path(name, file_type, encrypted=True)
        plaintext_path = self._get_path(name, file_type, encrypted=False)
        source_path = None
        is_encrypted_source = False

        if encrypted_path.exists():
             source_path = encrypted_path
             is_encrypted_source = True
             logger.debug(f"找到加密文件: {source_path}")
        elif plaintext_path.exists():
             source_path = plaintext_path
             is_encrypted_source = False # 文件存在但没有 .enc 后缀
             logger.debug(f"找到明文文件（或inplace加密的文件）: {source_path}")
        else:
             logger.warning(f"文件 '{name}' (类型: {file_type}) 不存在 (既没有 {encrypted_path.name} 也没有 {plaintext_path.name})")
             return None
             
        logger.debug(f"尝试加载并解密文件: {source_path} (类型: {file_type}, 源是否标记加密: {is_encrypted_source})")

        try:
            # 1. 读取源文件字节
            with open(source_path, 'rb') as f:
                source_bytes = f.read()

            if not source_bytes:
                 logger.warning(f"源文件为空: {source_path}")
                 # 根据类型返回默认空值
                 if file_type == "json": return {}
                 if file_type == "text": return ""
                 if file_type == "binary": return b""
                 return None

            # 2. 解密或解析数据
            decrypted_data: Any = None
            
            if file_type == "json":
                decrypted_data = None
                try:
                    # Attempt 1: Assume entire file is a single encrypted block
                    # logger.debug(f"Attempt 1: Decrypting {source_path} as single block...")
                    decrypted_bytes = encryptor.decrypt(source_bytes)
                    try:
                        decrypted_data = json.loads(decrypted_bytes.decode('utf-8'))
                        logger.debug(f"Successfully decrypted {source_path} as a single block and parsed JSON.")
                    except (json.JSONDecodeError, UnicodeDecodeError) as e:
                        logger.error(f"Decryption of {source_path} as single block succeeded, but failed to parse result as JSON: {e}")
                        return None # Decrypted but not valid JSON for the context
                        
                except (ValueError, InvalidToken, TypeError, binascii.Error) as e1:
                    # Attempt 2: Assume file contains JSON structure with potentially nested encrypted values
                    logger.debug(f"Failed to decrypt {source_path} as single block ({e1}), trying to parse as JSON with nested encryption...")
                    try:
                        initial_data = json.loads(source_bytes.decode('utf-8'))
                        # Recursively decrypt, _recursive_decrypt now returns bytes for decrypted blocks
                        processed_data = self._recursive_decrypt(initial_data, encryptor) 
                        
                        # Final pass to parse bytes returned by _recursive_decrypt into JSON objects/strings
                        decrypted_data = self._finalize_decrypted_json(processed_data)
                        logger.debug(f"Successfully parsed {source_path} as JSON and recursively decrypted/finalized.")

                    except (json.JSONDecodeError, UnicodeDecodeError) as e2:
                        logger.error(f"File {source_path} could not be processed either as a single encrypted block or as JSON with nested encryption: {e2}")
                        return None
                    except Exception as e3: # Catch errors during recursive decrypt/finalize
                         logger.error(f"Unexpected error during recursive decryption/finalization of {source_path}: {e3}", exc_info=True)
                         return None
                    
            elif file_type == "text":
                # 文本文件被视为单一加密块
                try:
                    decrypted_bytes = encryptor.decrypt(source_bytes)
                    decrypted_data = decrypted_bytes.decode('utf-8')
                except (ValueError, InvalidToken, TypeError, binascii.Error) as decrypt_err:
                     logger.error(f"解密文本文件 {source_path} 失败: {decrypt_err}")
                     return None
                except UnicodeDecodeError as ue:
                     logger.error(f"解密后解码文本文件 {source_path} 为 UTF-8 失败: {ue}")
                     return None
            elif file_type == "binary":
                # 二进制文件被视为单一加密块
                 try:
                     decrypted_data = encryptor.decrypt(source_bytes)
                 except (ValueError, InvalidToken, TypeError, binascii.Error) as decrypt_err:
                     logger.error(f"解密二进制文件 {source_path} 失败: {decrypt_err}")
                     return None
            else:
                 raise ValueError(f"不支持的文件类型: {file_type}") 

            logger.debug(f"成功为 {source_path} 获取解密后的内容 (类型: {type(decrypted_data)})")
            return decrypted_data

        except InvalidToken:
             logger.error(f"解密文件 {source_path} 失败：无效的令牌（可能是密钥错误或数据损坏）")
             return None
        except Exception as e:
            logger.error(f"加载或解密文件 {source_path} 时发生意外错误: {e}", exc_info=True)
            return None

    # --- 加密方法 ---
    def encrypt_and_save_content(self, name: str, data: Any, encryptor: EnhancedAES256Encryptor, file_type: FileType = "json", inplace: bool = False) -> bool:
        """
        加密数据并保存到文件。

        参数:
            name: 文件基础名称。
            data: 要加密的明文数据 (dict/list for json, str for text, bytes for binary)。
            encryptor: 加密器实例。
            file_type: 文件类型，默认为'json'。
            inplace: 是否原地加密（不改变文件名，不添加 .enc 后缀）。
            
        返回:
            是否成功加密并保存
        """
        # 确定目标路径
        if inplace:
            target_path = self._get_path(name, file_type, encrypted=False)  # 原地加密，覆盖原文件
            logger.info(f"原地加密，目标路径: {target_path} (类型: {file_type})")
        else:
            target_path = self._get_path(name, file_type, encrypted=True)  # 默认行为，创建 .enc 文件
            logger.info(f"加密并保存到新路径: {target_path} (类型: {file_type})")
        try:
            # 1. 将数据转换为字节
            plaintext_bytes: bytes
            if file_type == "json":
                if not isinstance(data, (dict, list)):
                     raise TypeError("JSON 类型需要 dict 或 list 数据进行加密")
                plaintext_bytes = json.dumps(data, ensure_ascii=False).encode('utf-8')
            elif file_type == "text":
                if not isinstance(data, str):
                    data_str = str(data)  # 尝试转换为字符串
                    logger.warning(f"Text类型需要str数据，自动转换 {type(data)} 为str")
                else:
                    data_str = data
                plaintext_bytes = data_str.encode('utf-8')
            elif file_type == "binary":
                if not isinstance(data, bytes):
                     raise TypeError("Binary 类型需要 bytes 数据进行加密")
                plaintext_bytes = data
            else:
                 raise ValueError(f"不支持的文件类型: {file_type}")
                 
            logger.debug(f"将数据转换为 {len(plaintext_bytes)} 字节进行加密")

            # 2. 加密字节
            encrypted_bytes = encryptor.encrypt(plaintext_bytes)
            logger.debug(f"加密后生成 {len(encrypted_bytes)} 字节数据")

            # 3. 保存加密字节
            target_path.parent.mkdir(parents=True, exist_ok=True)
            with open(target_path, 'wb') as f:
                f.write(encrypted_bytes)

            logger.info(f"成功加密并保存数据到 {target_path}")
            
            # 4. 如果不是原地操作，且保存成功，删除原始明文文件
            if not inplace:
                plaintext_path = self._get_path(name, file_type, encrypted=False)
                if plaintext_path.exists() and plaintext_path != target_path:
                    try:
                        plaintext_path.unlink()
                        logger.info(f"已删除原始明文文件: {plaintext_path}")
                    except OSError as e:
                        logger.error(f"删除原始明文文件 {plaintext_path} 时出错: {e}")
                        # 继续处理，不影响整体成功状态
            
            return True
        except Exception as e:
            logger.error(f"加密并保存文件 {target_path} 失败: {e}", exc_info=True)
            return False

    def config_exists(self, filename: str) -> bool:
        """检查配置文件是否存在。"""
        file_path = self._get_path(filename)
        return file_path.exists()

    def get_raw_config_data(self, filename: str) -> Optional[Dict]:
        """
        获取原始配置数据，不进行解密处理。
        
        参数:
            filename: 配置文件名称或绝对路径
            
        返回:
            原始配置数据的字典，如果文件不存在或读取失败则返回None
        """
        file_path = self._get_path(filename)
        if not file_path.exists():
            logger.warning(f"配置文件不存在：{file_path}")
            return None
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                content = f.read()
                if not content:
                    return {} # 对于空文件返回空字典
                return json.loads(content)
        except json.JSONDecodeError as e:
            logger.error(f"解析 {file_path} 的JSON时出错：{e}")
            return None # 表示出错
        except Exception as e:
            logger.error(f"读取配置文件 {file_path} 时出错：{e}")
            return None # 表示出错

    def get_raw_file_data(self, name: str, file_type: Optional[FileType] = None) -> Optional[bytes]:
        """
        获取文件的原始字节内容（优先获取加密文件）。

        参数:
            name: 文件基础名称。
            file_type: 可选，指定文件类型。如果为None，将尝试所有类型。

        返回:
            文件的原始字节，如果未找到则为None。
        """
        types_to_check = [file_type] if file_type else list(self.FILE_EXTENSIONS.keys())
        
        for type_key in types_to_check:
            encrypted_path = self._get_path(name, type_key, encrypted=True)
            plaintext_path = self._get_path(name, type_key, encrypted=False)

            target_path = None
            if encrypted_path.exists():
                target_path = encrypted_path
                logger.debug(f"找到加密文件: {encrypted_path}")
            elif plaintext_path.exists():
                target_path = plaintext_path
                logger.debug(f"找到明文文件: {plaintext_path}")
            
            if target_path:
                try:
                    with open(target_path, 'rb') as f:
                        raw_data = f.read()
                        logger.debug(f"成功读取原始文件: {target_path} ({len(raw_data)} 字节)")
                        return raw_data
                except Exception as e:
                    logger.error(f"读取原始文件 {target_path} 时出错: {e}")
                    return None

        # 没有找到任何匹配的文件
        if file_type:
            logger.warning(f"未找到文件 '{name}' (类型: {file_type}) 的原始数据")
        else:
            logger.warning(f"未找到文件 '{name}' (任何类型) 的原始数据")
        return None

    # --- JSON 专有方法 ---

    def get_value(self, name: str, key_path: Union[str, List[str]], encryptor: EnhancedAES256Encryptor) -> Optional[Any]:
        """
        获取JSON文件中指定键路径的值。

        参数:
            name: 文件基础名称。
            key_path: 点分隔的字符串或列表形式的键路径。
            encryptor: 加密器实例。

        返回:
            获取到的值，如果键不存在或出错则为None。
        """
        logger.debug(f"尝试从JSON文件 '{name}' 获取键路径 '{key_path}'")
        data = self.get_decrypted_file_content(name, encryptor, "json")

        if data is None:
            logger.warning(f"无法获取或解密JSON文件 '{name}' 以获取值")
            return None
        if not isinstance(data, dict):
            logger.warning(f"文件 '{name}' 解密后不是字典，无法获取键值")
            return None

        keys = key_path.split('.') if isinstance(key_path, str) else key_path
        current = data
        try:
            for key in keys:
                if isinstance(current, dict):
                    current = current[key]
                elif isinstance(current, list):
                    try:
                        idx = int(key)
                        current = current[idx]
                    except (ValueError, IndexError):
                        logger.warning(f"无效的列表索引 '{key}' 在路径 '{key_path}' 中，文件 '{name}'")
                        return None
                else:
                    logger.warning(f"路径 '{key_path}' 中的非结构化数据，文件 '{name}'")
                    return None
            logger.debug(f"成功获取键路径 '{key_path}' 的值")
            return current
        except (KeyError, IndexError):
            logger.warning(f"键路径 '{key_path}' 在文件 '{name}' 中不存在")
            return None
        except Exception as e:
            logger.error(f"获取键路径 '{key_path}' 时出错 ({name}): {e}", exc_info=True)
            return None

    def set_value(self, name: str, key_path: Union[str, List[str]], value: Any, encryptor: EnhancedAES256Encryptor) -> bool:
        """
        设置JSON文件中指定键路径的值。

        参数:
            name: 文件基础名称。
            key_path: 点分隔的字符串或列表形式的键路径。
            value: 要设置的值。
            encryptor: 加密器实例。
            
        返回:
            是否成功设置值
        """
        logger.debug(f"尝试在JSON文件 '{name}' 中设置键路径 '{key_path}'")
        
        # 处理JSON值字符串（尝试解析为JSON对象）
        if isinstance(value, str):
            try:
                # 尝试解析为JSON对象（如果是有效的JSON字符串）
                if (value.startswith('{') and value.endswith('}')) or \
                   (value.startswith('[') and value.endswith(']')) or \
                   value.lower() in ('true', 'false', 'null'):
                    parsed_value = json.loads(value)
                    logger.info(f"将字符串 '{value[:20]}...' 解析为JSON值: {type(parsed_value)}")
                    value = parsed_value
            except json.JSONDecodeError:
                # 不是有效的JSON，保持为字符串
                pass
        
        # 1. 获取当前解密后的数据
        data = self.get_decrypted_file_content(name, encryptor, "json")

        if data is None:
             # 检查文件是否存在
             if not self.file_exists(name, "json"):
                  logger.info(f"JSON文件 '{name}' 不存在，将创建新文件。")
                  data = {} # 创建新的空对象
             else:
                  # 文件存在但无法解密
                  logger.error(f"无法解密现有JSON文件 '{name}' 以设置值")
                  return False
        elif not isinstance(data, dict):
            # 已存在且已解密，但不是字典
            logger.error(f"文件 '{name}' 不是有效的JSON对象，无法设置键值")
            return False

        # 2. 导航或创建路径并设置值
        keys = key_path.split('.') if isinstance(key_path, str) else key_path
        current = data
        try:
            # 处理除最后一个键之外的所有键
            for i, key in enumerate(keys[:-1]):
                if isinstance(current, dict):
                    if key not in current:
                        current[key] = {} # 如果不存在则创建嵌套字典
                    current = current[key]
                elif isinstance(current, list):
                    # 如果是列表，则尝试使用索引
                    try:
                        idx = int(key)
                        # 确保索引有效
                        if idx < 0 or idx >= len(current):
                            raise IndexError(f"列表索引 {idx} 超出范围 [0, {len(current) - 1}]")
                        current = current[idx]
                    except ValueError:
                        logger.error(f"无效的列表索引 '{key}' 在路径 '{key_path}' 中")
                        return False
                else:
                     logger.error(f"路径 '{key_path}' 中的非字典/列表结构无法设置子键")
                     return False

            # 设置最后一个键的值
            last_key = keys[-1]
            if isinstance(current, dict):
                current[last_key] = value
                logger.debug(f"成功在字典中设置键 '{last_key}'")
            elif isinstance(current, list):
                # 处理列表索引
                try:
                    idx = int(last_key)
                    if idx < 0 or idx >= len(current):
                        raise IndexError(f"列表索引 {idx} 超出范围 [0, {len(current) - 1}]")
                    current[idx] = value
                    logger.debug(f"成功在列表中设置索引 '{last_key}'")
                except ValueError:
                    logger.error(f"无效的列表索引 '{last_key}' 在路径 '{key_path}' 中")
                    return False
            else:
                 logger.error(f"无法在非字典/列表结构中设置最终键 '{last_key}'")
                 return False

            # 3. 加密并保存回文件
            return self.encrypt_and_save_content(name, data, encryptor, "json")

        except Exception as e:
            logger.error(f"设置键路径 '{key_path}' 时出错 ({name}): {e}", exc_info=True)
            return False